home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1989
/
06
/
peeper.asm
< prev
next >
Wrap
Assembly Source File
|
1989-07-31
|
3KB
|
142 lines
;****************************************************************
;*
;* PEEPER.ASM - Assembly subroutines to move memory from a 4G linear
;* address into a buffer in the current data segment
;*
;* Assembled using Microsoft Macro Assembler 5.1
;*
;****************************************************************
;* Need to use 80386 protected mode instructions
.386P
KBC_IBF_BIT EQU 02H
KBC_WOP_CMD EQU 0D1H
KBC_ROP_CMD EQU 0D0H
A20_OFF_DATA EQU 0DDH
A20_ON_DATA EQU 0DFH
KBC_NOP_CMD EQU 0FFH
KBC_DATA_PORT EQU 060H
KBC_CMD_PORT EQU 064H
GA20_FAIL_ERR_CODE EQU 0FFFFH
_TEXT segment use16 public 'CODE'
assume cs:_TEXT,ds:_TEXT,es:_TEXT,ss:_TEXT
;****************************************************************
;* get_high_mem(dest,len,source) - copy memory from source to dest (len bytes)
;* Entry - dest - buffer in current DS
;* len - size of buffer in bytes
;* source - 32-bit linear address of source memory
;* Exit - gs: set to zero
;* WARNING: Forces GateA20 low when done
;****************************************************************
public _get_high_mem
ghm_dest equ word ptr [bp+4]
ghm_len equ word ptr [bp+6]
ghm_source equ dword ptr [bp+8]
_get_high_mem proc near
push bp
mov bp, sp
push di
mov al, 080h ; allow normal A20
call gate_A20
xor ax, ax
mov gs, ax ; zero out gs
mov ax, ds
mov es, ax ; es := ds
mov di, ghm_dest
mov cx, ghm_len
mov ebx, ghm_source
jcxz ghm_bottom
ghm_top:
mov al, byte ptr gs:[ebx]
inc ebx
stosb
loop ghm_top
ghm_bottom:
xor al, al ; cripple A20 for DOS
call gate_A20
pop di
pop bp
ret
_get_high_mem endp
;****************************************************************
;* gate_A20(how) - set gateA20 to the desired state
;* Entry - AL==80h => A20 on
;* AL==00h => A20 off
;* Exit - GateA20 in desired state
;* WARNING: Assumes preferred states of output port bits
;****************************************************************
;
; gate_A20 - set gateA20 to the desired state
; Entry - AL==80h => A20 on (no 1M wrap)
; AL==00h => A20 off (1M wrap)
;
gate_A20 proc near
test al,080H ; al&80 = 0 ?
jnz short ga20_on
; al is zero, turn a20 off
mov ah,A20_OFF_DATA ; kbc off gate a20
call empty_KBC ; clear to use
jnz short ga20_err ; didn't clear
jmp short ga20_KBC_ctl ; cleared, go fix KBC A20
ga20_on:
mov ah,A20_ON_DATA ; kbc on gate a20 if needed
ga20_KBC_ctl:
mov al,KBC_WOP_CMD ; Write Output Port
out KBC_CMD_PORT,al ; command it
call empty_KBC
jnz short ga20_err
mov al,ah
out KBC_DATA_PORT,al
call empty_KBC ; wait till it clears
jnz short ga20_err ; didn't clear
mov al,KBC_NOP_CMD ; flush it through
out KBC_CMD_PORT,al ; command it
call empty_KBC
jnz short ga20_err
; we're here, it worked!!
ga20_ok:
xor ax,ax
jmp short ga20_out
ga20_err:
mov ax,GA20_FAIL_ERR_CODE
ga20_out:
ret
gate_A20 endp
;
; empty_KBC - Empty keyboard controller input buffer
; Entry - none
; Exit - bashes AL
;
empty_KBC proc near
push cx ; save reg
xor cx,cx ; set for max timeout
empty_KBC_loop:
in al,KBC_CMD_PORT ; get KBC status
test al,KBC_IBF_BIT ; check IBF bit
loopnz empty_KBC_loop ; try till timeout
pop cx ; restore reg
ret ; that's all folks
empty_KBC endp
_TEXT ends
end